package com.nannybear.View;

import android.graphics.Color;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.nannybear.Model.ProgressItem;
import com.nannybear.R;

import java.util.Observable;
import java.util.Observer;

/**
 * \brief The home screen
 * \author Audrey LOISEAU
 * \date 15-03-2015
 */

/********************************* COPYRIGHT *********************************
 * Copyright (c) 2015, Audrey LOISEAU and Benjamin LANCINOT.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************************/

public class HomeScreen extends Screen implements Observer{
    /********** DECLARATIONS **********/
    //Variables
    private Double newValueState;
    private final static double QUIET = 1.0;
    private final static double NOISY = 2.0;
    private final static double AGITATED = 3.0;
    private final static double DARK = 1.0;
    private final static double DIM = 2.0;
    private final static double BRIGHT = 3.0;
    private String gender;

    // Widget of the view
    private ImageView indicate_warning_temp, indicate_warning_hum, image_bb, wifi, light_bulb;
    private TextView temp_value, warning_temp, warning_exp_temp, home_txt_temp, home_temp_unity;
    private TextView humidity_value, warning_hum, warning_exp_hum, home_txt_hum, home_hum_unity;
    private TextView light_value, baby_state;

    // Handler
    private final Handler myHandler = new Handler();

    /************ METHODS ************/
    /**
     * \brief Constructor
     */
    public HomeScreen() {
        super(R.layout.home_screen, false, false);
        setNewValueState(0.0);
    }

    /**
     * \brief Update information with new value
     * \param obs   The observable class
     * \param obj   The object received
     */
    public void update(Observable obs, Object obj){
        String name = obs.getClass().getSimpleName();
        if(name.equalsIgnoreCase("Temperature")){
            updateValue(temp_value, obj.toString());
        }
        if(name.equalsIgnoreCase("Humidity")){
            updateValue(humidity_value, obj.toString());
        }
        if(name.equalsIgnoreCase("Brightness")){
            updateBrightness(obj.toString());
        }
        if(name.equalsIgnoreCase("BabyState")){
            updateState((ProgressItem) obj, gender);
        }
    }

    /**
     * \brief Handler to update the value of temperature or humidity
     * \param widget    The widget to change
     * \param value The value
     */
    public void updateValue(final TextView widget, final String value){
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                widget.setText(value);
            }
        });
    }

    /**
     * \brief Change brightness information
     * \param valueLight    The light value
     */
    private void changeBrightness(String valueLight){
        if(!valueLight.equals("")) {
            Double value = Double.parseDouble(valueLight);
            if (value == DARK) {
                light_value.setText("Dark");
                light_bulb.setBackgroundResource(R.drawable.light_bulb_off);
            }
            if (value == DIM) {
                light_value.setText("Dim light");
                light_bulb.setBackgroundResource(R.drawable.light_bulb_dim);
            }
            if (value == BRIGHT) {
                light_value.setText("Bright");
                light_bulb.setBackgroundResource(R.drawable.light_bulb_on);
            }
        }
    }

    /**
     * \brief Handler to change the brightness
     * \param valueLight    The new light value
     */
    void updateBrightness(final String valueLight) {
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                changeBrightness(valueLight);
            }
        });
    }

    /**
     * \brief Change baby state information
     * \param pI    The progress item
     * \param gender    The baby gender
     */
    private void changeState(ProgressItem pI, String gender){
        if (pI.state == QUIET) {
            baby_state.setTextColor(Color.parseColor("#34B536"));
            baby_state.setText("Quiet !");
            if(gender.equals("neutral")){
                image_bb.setBackgroundResource(R.drawable.neutra_happy);
            }
            if(gender.equals("girl")){
                image_bb.setBackgroundResource(R.drawable.girl_happy);
            }
            if(gender.equals("boy")){
                image_bb.setBackgroundResource(R.drawable.boy_happy);
            }
        }
        if (pI.state == NOISY) {
            baby_state.setTextColor(Color.parseColor("#B5262F"));
            baby_state.setText("Noisy !");
            if(gender.equals("neutral")) {
                image_bb.setBackgroundResource(R.drawable.neutral_noise);
            }
            if(gender.equals("girl")){
                image_bb.setBackgroundResource(R.drawable.girl_noise);
            }
            if(gender.equals("boy")){
                image_bb.setBackgroundResource(R.drawable.boy_noise);
            }
        }
        if (pI.state == AGITATED) {
            baby_state.setTextColor(Color.parseColor("#FC843A"));
            baby_state.setText("Agitated !");
            if (gender.equals("neutral")) {
                image_bb.setBackgroundResource(R.drawable.neutral_agitated);
            }
            if (gender.equals("girl")) {
                image_bb.setBackgroundResource(R.drawable.girl_agitated);
            }
            if (gender.equals("boy")) {
                image_bb.setBackgroundResource(R.drawable.boy_agitated);
            }
        }
    }

    /**
     * \brief Handler to change the baby state
     * \param pI    The progress item
     * \param gender    The baby gender
     */
    public void updateState(final ProgressItem pI, final String gender) {
        myHandler.post(new Runnable() {
            @Override
            public void run() {
                changeState(pI,gender);
            }
        });
    }

    /**
     * \brief Change the home screen to warm the user of a temperature warning
     * \param warning   The warning (\e string)
     */
    public void changeToWarnTemp(String warning){
        int visibility ,colorWarning,colorTxt, colorValue;
        if (warning.equals(" perfect")){
            visibility = View.GONE;
            colorWarning = Color.parseColor("#D3CDCD");
            colorTxt = Color.parseColor("#D3CDCD");
            colorValue = Color.parseColor("#FFFFFF");
        }
        else {
            visibility = View.VISIBLE;
            colorTxt = Color.parseColor("#828086");
            colorValue = Color.parseColor("#A9A8AD");
            if (warning == " too cold") {
                colorWarning = Color.parseColor("#5AAFED");
            }
            else {
                colorWarning = Color.parseColor("#B5262F");
            }
        }
        indicate_warning_temp.setVisibility(visibility);
        warning_exp_temp.setVisibility(visibility);
        warning_exp_temp.setText(warning);
        warning_exp_temp.setTextColor(colorWarning);
        warning_temp.setVisibility(visibility);
        warning_temp.setTextColor(colorWarning);
        home_txt_temp.setTextColor(colorTxt);
        home_temp_unity.setTextColor(colorValue);
        temp_value.setTextColor(colorValue);
    }

    /**
     * \brief Change the home screen to warm the user of a humidity warning
     * \param warning   The warning (\e string)
     */
    public void changeToWarnHum(String warning){
        int visibility ,colorWarning, colorTxt, colorValue;
        if (warning.equals(" perfect")) {
            visibility = View.GONE;
            colorWarning = Color.parseColor("#D3CDCD");
            colorTxt = Color.parseColor("#D3CDCD");
            colorValue = Color.parseColor("#FFFFFF");
        }
        else {
            visibility = View.VISIBLE;
            colorTxt = Color.parseColor("#828086");
            colorValue = Color.parseColor("#A9A8AD");
            if (warning.equals(" too wet")) {
                colorWarning = Color.parseColor("#B5262F");
            }
            else {
                colorWarning = Color.parseColor("#5AAFED");
            }
        }

        indicate_warning_hum.setVisibility(visibility);
        warning_exp_hum.setVisibility(visibility);
        warning_exp_hum.setText(warning);
        warning_exp_hum.setTextColor(colorWarning);
        warning_hum.setVisibility(visibility);
        warning_hum.setTextColor(colorWarning);
        home_txt_hum.setTextColor(colorTxt);
        home_hum_unity.setTextColor(colorValue);
        humidity_value.setTextColor(colorValue);
    }

    /**
     * \brief Change the connection status
     * \param isConnected   The connection state
     */
    public void changeConnectionStatus(boolean isConnected){
        if(isConnected){
            wifi.setVisibility(View.VISIBLE);
        }
        else{
            wifi.setVisibility(View.GONE);
        }
    }

    /**
     * \brief Update the view
     * \param isConnected   The connection state
     * \param tempWarning   The temperature warning
     * \param humWarning   The humidity warning
     * \param pI    The progress item
     * \param temperature   The temperature value
     * \param hum   The humidity value
     * \param light The light value
     */
    public void updateView(boolean isConnected, String tempWarning, String humWarning, ProgressItem pI, double temperature, double hum, String light){
        if (Double.parseDouble(tempWarning) == 1) {
            tempWarning = " perfect";
        }
        else if (Double.parseDouble(tempWarning) == 2 || Double.parseDouble(tempWarning) == 4) {
            tempWarning = " too cold";
        }
        else{
            tempWarning = " too hot";
        }
        if (Double.parseDouble(humWarning) == 1) {
            humWarning = " perfect";
        }
        else if (Double.parseDouble(humWarning) == 2 || Double.parseDouble(humWarning) == 4) {
            humWarning = " too dry";
        }
        else{
            humWarning = " too wet";
        }
        changeToWarnHum(humWarning);
        changeToWarnTemp(tempWarning);
        changeState(pI,this.gender);
        int temp = (int)(temperature*10);
        temp_value.setText(String.valueOf(temp/10.0));
        temp = (int)(hum*10);
        humidity_value.setText(String.valueOf(temp/10.0));
        changeBrightness(light);
        changeConnectionStatus(isConnected);
    }

    /**
     * \brief Show the view
     * \param thresholdTemp The value of temperature threshold
     * \param thresholdHum  The value of humidity threshold
     */
    public void display(int thresholdTemp, int thresholdHum){
        getTempButton().setBackgroundResource(getTempDrawable()[thresholdTemp]);
        getHumidityButton().setBackgroundResource(getHumDrawable()[thresholdHum]);
        getHomeButton().setBackgroundResource(R.drawable.home_active);
    }

    /**
     * \brief Close the view (empty)
     */
    public void close() {
    }


    /*********** ACCESSORS ***********/
    /**
     * \brief Set method for the temperature value
     */
    public void setTemp_value(TextView temp_value) {
        this.temp_value = temp_value;
    }

    /**
     * \brief Set method for the light value
     */
    public void setLight_value(TextView light_value) {
        this.light_value = light_value;
    }

    /**
     * \brief Set method for the humidity value
     */
    public void setHumidity_value(TextView humidity_value) {
        this.humidity_value = humidity_value;
    }

    /**
     * \brief Set method for the new value state
     */
    public void setNewValueState(double newValueState) {
        this.newValueState = newValueState;
    }

    /**
     * \brief Set method for the warning temperature (image)
     */
    public void setIndicate_warning_temp(ImageView indicate_warning_temp) {
        this.indicate_warning_temp = indicate_warning_temp;
    }

    /**
     * \brief Set method for the warning humidity (image)
     */
    public void setIndicate_warning_hum(ImageView indicate_warning_hum) {
        this.indicate_warning_hum = indicate_warning_hum;
    }

    /**
     * \brief Set method for the warning temperature (textView)
     */
    public void setWarning_temp(TextView warning_temp) {
        this.warning_temp = warning_temp;
    }

    /**
     * \brief Set method for the warning temperature explantation (textView)
     */
    public void setWarning_exp_temp(TextView warning_exp_temp) {
        this.warning_exp_temp = warning_exp_temp;
    }

    /**
     * \brief Set method for the warning humidity explantation (textView)
     */
    public void setWarning_exp_hum(TextView warning_exp_hum) {
        this.warning_exp_hum = warning_exp_hum;
    }

    /**
     * \brief Set method for the text temperature
     */
    public void setHome_txt_temp(TextView home_txt_temp) {
        this.home_txt_temp = home_txt_temp;
    }

    /**
     * \brief Set method for the temperature unit
     */
    public void setHome_temp_unity(TextView home_temp_unity) {
        this.home_temp_unity = home_temp_unity;
    }

    /**
     * \brief Set method for the text humidity
     */
    public void setHome_txt_hum(TextView home_txt_hum) {
        this.home_txt_hum = home_txt_hum;
    }

    /**
     * \brief Set method for the humidity unit
     */
    public void setHome_hum_unity(TextView home_hum_unity) {
        this.home_hum_unity = home_hum_unity;
    }

    /**
     * \brief Set method for the baby picture
     */
    public void setImage_bb(ImageView image_bb) {
        this.image_bb = image_bb;
    }

    /**
     * \brief Set method for the baby state
     */
    public void setBaby_state(TextView baby_state) {
        this.baby_state = baby_state;
    }

    /**
     * \brief Set method for the baby gender
     */
    public void setGender(String gender) {
        this.gender = gender;
    }

    /**
     * \brief Set method for the light bulb
     */
    public void setLight_bulb(ImageView light_bulb) {
        this.light_bulb = light_bulb;
    }

    /**
     * \brief Set method for the wifi picture
     */
    public void setWifi(ImageView wifi) {
        this.wifi = wifi;
    }

    /**
     * \brief Set method for the warning humidity
     */
    public void setWarning_hum(TextView warning_hum) {
        this.warning_hum = warning_hum;
    }
}
